package com.core.common.utils;

import com.core.common.domain.response.MyLocation;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @author hl
 * @version 1.0.0
 * @ClassName GeodesyUtil.java
 * @Description 经纬度、距离 工具
 * @createTime 2023年06月28日 14:48:00
 */
public class GeodesyUtil {

    /**
     * 根据经纬度，计算两点间的距离、方位、反方位
     * @param longitudeFrom  第一个点的经度
     * @param latitudeFrom  第一个点的纬度
     * @param longitudeTo 第二个点的经度
     * @param latitudeTo  第二个点的纬度
     * @param accurate  保留小数点几位
     */
    public static double getDistance(double longitudeFrom, double latitudeFrom, double longitudeTo, double latitudeTo,int accurate) {
        GlobalCoordinates source = new GlobalCoordinates(latitudeFrom, longitudeFrom);
        GlobalCoordinates target = new GlobalCoordinates(latitudeTo, longitudeTo);
        //创建GeodeticCalculator，调用计算方法，传入坐标系、经纬度得到GeodeticCurve，用GeodeticCurve获取距离、方位、反方位
        GeodeticCurve geodeticCurve = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.WGS84, source, target);
        //获取两点的方位
        double azimuth = geodeticCurve.getAzimuth();
        //获取两点之间的距离
        double distance = geodeticCurve.getEllipsoidalDistance();
      //  double v = distance*1000;//距离转为毫米
        //保留数据小数点位数且四舍五入
//        BigDecimal bigDecimal = new BigDecimal(v).setScale(accurate,BigDecimal.ROUND_HALF_UP);
//        double result = bigDecimal.doubleValue();
        System.out.println("两个坐标之间的距离是"+ distance + "米");
        System.out.println("两个坐标的方向是"+azimuth);
        return distance;
    }



    /**
     * 根据开始坐标点，角度，计算结束点坐标
     * @param longitudeFrom 开始点经度
     * @param latitudeFrom  开始点纬度
     * @param startAngle 方向（以起点为中心）如果是90角，startAngle=90，表示纬度不变，经度向东移动增大  正北方向是0，正东方向是90
     * @param distance 距离（单位：m）
     */
    public static MyLocation getGlobalCoordinates(double longitudeFrom, double latitudeFrom, double startAngle, double distance){

        //经纬度对象
        GlobalCoordinates startGlobalCoordinates = new GlobalCoordinates(latitudeFrom, longitudeFrom);
        //计算的坐标对象
        GlobalCoordinates globalCoordinates = new GeodeticCalculator().calculateEndingGlobalCoordinates(Ellipsoid.WGS84, startGlobalCoordinates, startAngle, distance);
        //获取纬度
        double latitude = globalCoordinates.getLatitude();
        //获取经度
        double longitude = globalCoordinates.getLongitude();
        System.out.println("坐标经度="+longitude+",坐标纬度="+latitude);
        MyLocation location= new MyLocation().setLongitude(longitude).setLatitude(latitude);
        return location;
    }


    /***
     * 根据金纬度，距离 计算四至范围
     * @param longitudeFrom
     * @param latitudeFrom
     * @param distance
     */
    public static Map<Double, MyLocation.LimitPoint>  getLimitPoint(double longitudeFrom, double latitudeFrom, double distance){
        Map<Double, MyLocation.LimitPoint> map = new HashMap<>();
        MyLocation.LimitPoint limitPoint=new MyLocation.LimitPoint()
                .setDistance(distance);
        map.put(distance,limitPoint);

        MyLocation location0 = getGlobalCoordinates(121.18, 31.16, 0, distance);
        setPointLimit(limitPoint,location0);
        MyLocation location90 = getGlobalCoordinates(121.18, 31.16, 90, distance);
        setPointLimit(limitPoint,location90);
        MyLocation location180 = getGlobalCoordinates(121.18, 31.16, 180, distance);
        setPointLimit(limitPoint,location180);
        MyLocation location270 = getGlobalCoordinates(121.18, 31.16, 270, distance);
        setPointLimit(limitPoint,location270);

        return map;

    }


    private static void  setPointLimit(MyLocation.LimitPoint limitPoint,MyLocation location){
        if (null == limitPoint.getLatitudeMin()){
            limitPoint.setLatitudeMin(location.getLatitude());
        }
        if (limitPoint.getLatitudeMin() > location.getLatitude()){
            limitPoint.setLatitudeMin(location.getLatitude());
        }
        if (null == limitPoint.getLatitudeMax()){
            limitPoint.setLatitudeMax(location.getLatitude());
        }
        if (limitPoint.getLatitudeMax() < location.getLatitude()){
            limitPoint.setLatitudeMax(location.getLatitude());
        }

        if (null == limitPoint.getLongitudeMin()){
            limitPoint.setLongitudeMin(location.getLongitude());
        }
        if (limitPoint.getLongitudeMin() > location.getLongitude()){
            limitPoint.setLongitudeMin(location.getLongitude());
        }
        if (null == limitPoint.getLongitudeMax()){
            limitPoint.setLongitudeMax(location.getLongitude());
        }
        if (limitPoint.getLongitudeMax() <  location.getLongitude()){
            limitPoint.setLongitudeMax(location.getLongitude());
        }

    }





}
